<template>
  <div class="chat-bg">
    <!-- 聊天头部 -->
    <div class="chat-header">
      <van-icon name="arrow-left" class="chat-back" @click="goBack" />
      <div class="chat-user-info" @click="goToUserProfile">
        <img class="chat-avatar" :src="chatUser.avatar" />
        <div class="chat-user-details">
          <div class="chat-user-name">{{ chatUser.name }}</div>
          <div class="chat-user-status">
            <span class="status-dot" :class="chatUser.status === '在线' ? 'online' : 'offline'"></span>
            {{ chatUser.status }}
          </div>
        </div>
      </div>
      <van-icon name="ellipsis" class="chat-more" @click="showMoreOptions" />
    </div>

    <!-- 聊天消息列表 -->
    <div class="chat-messages" ref="messageContainer" @scroll.passive="onScroll">
      <van-loading v-if="loading && messages.length === 0" size="24px" color="#1677ff" vertical>加载中...</van-loading>
      <div v-if="!loading && messages.length === 0" class="no-message">暂无消息</div>
      <div
        v-for="(message, index) in messages"
        :key="(message.id ? message.id : 'local') + '_' + (message.timestamp || '') + '_' + index"
        :class="[
          'message-item',
          message.type === 0 ? 'message-system' : (message.isSelf ? 'message-self' : 'message-other')
        ]"
      >
        <template v-if="message.type === 0">
          <div class="system-message-content">{{ message.text }}</div>
        </template>
        <template v-else-if="message.type === 3">
          <img
            class="message-avatar"
            :src="message.isSelf ? (message.avatarPath || currentUser.avatar) : (message.avatarPath || chatUser.avatar)"
            @click="message.isSelf ? goToMyProfile() : goToUserProfile()"
          />
          <div class="message-content">
            <div class="message-bubble emoji-bubble">
              <template v-if="isImage(message.text)">
                <img class="pic-img" :src="message.text" alt="图片" @click="previewImage(message.text)" />
              </template>
              <template v-else>
                <span v-if="isEmoji(message.text)" class="emoji-content">{{ message.text }}</span>
                <img v-else class="emoji-img" :src="message.text" alt="emoji" />
              </template>
            </div>
          </div>
        </template>
        <template v-else-if="message.type === 43">
          <img
            class="message-avatar"
            :src="message.isSelf ? (message.avatarPath || currentUser.avatar) : (message.avatarPath || chatUser.avatar)"
            @click="message.isSelf ? goToMyProfile() : goToUserProfile()"
          />
          <div class="message-content">
            <div class="message-bubble video-bubble">
              <div class="video-thumb-wrapper" @click="playVideo(message)">
                <img v-if="message.thumbnail" :src="message.thumbnail" class="video-thumb" alt="视频缩略图" />
                <video v-else :src="message.url" class="video-thumb" preload="metadata" muted></video>
                <div class="video-play-btn"><van-icon name="play-circle-o" /></div>
              </div>
              <div class="message-time">{{ formatTime(message.timestamp) }}</div>
            </div>
          </div>
        </template>
        <template v-else-if="message.type === 34">
          <img
            class="message-avatar"
            :src="message.isSelf ? (message.avatarPath || currentUser.avatar) : (message.avatarPath || chatUser.avatar)"
            @click="message.isSelf ? goToMyProfile() : goToUserProfile()"
          />
          <div class="message-content">
            <div class="message-bubble voice-bubble" @click="playVoice(message)">
              <van-icon name="volume-o" class="voice-icon" />
              <span class="voice-duration">{{ message.duration ? message.duration + '″' : '' }}</span>
            </div>
            <div class="message-time">{{ formatTime(message.timestamp) }}</div>
          </div>
        </template>
        <template v-else-if="message.type === 49">
          <img
            class="message-avatar"
            :src="message.isSelf ? (message.avatarPath || currentUser.avatar) : (message.avatarPath || chatUser.avatar)"
            @click="message.isSelf ? goToMyProfile() : goToUserProfile()"
          />
          <div class="message-content">
            <div class="message-bubble card-bubble">
              <!-- 引用消息 -->
              <div v-if="message.referText" class="refer-block">
                <div class="refer-title">引用</div>
                <div class="refer-content">{{ message.referText }}</div>
              </div>
              <!-- 文件消息 -->
              <div v-else-if="message.fileName" class="file-block" @click="downloadFile(message)">
                <van-icon name="description" class="file-icon" />
                <div class="file-info">
                  <div class="file-name">{{ message.fileName }}</div>
                  <div class="file-size">{{ formatFileSize(message.fileSize) }}</div>
                </div>
                <van-icon name="arrow" class="file-arrow" />
              </div>
              <!-- 分享链接 -->
              <div v-else-if="message.url && message.title" class="link-block" @click="openLink(message.url)">
                <img v-if="message.thumbnail" :src="message.thumbnail" class="link-thumb" />
                <div class="link-info">
                  <div class="link-title">{{ message.title }}</div>
                  <div class="link-desc">{{ message.description }}</div>
                  <div class="link-url">{{ message.url }}</div>
                </div>
                <van-icon name="arrow" class="link-arrow" />
              </div>
              <!-- 转账消息 -->
              <div v-else-if="message.feeDesc || message.payMemo" class="transfer-block">
                <van-icon name="gold-coin-o" class="transfer-icon" />
                <div class="transfer-info">
                  <div class="transfer-amount">{{ message.feeDesc }}</div>
                  <div class="transfer-memo">{{ message.payMemo }}</div>
                </div>
              </div>
              <!-- 兜底：普通文本 -->
              <div v-else class="card-default">{{ message.text }}</div>
            </div>
            <div class="message-time">{{ formatTime(message.timestamp) }}</div>
          </div>
        </template>
        <template v-else>
          <img
            class="message-avatar"
            :src="message.isSelf ? (message.avatarPath || currentUser.avatar) : (message.avatarPath || chatUser.avatar)"
            @click="message.isSelf ? goToMyProfile() : goToUserProfile()"
          />
          <div class="message-content">
            <div class="message-bubble">
              <div class="message-text">{{ message.text }}</div>
              <div class="message-time">{{ formatTime(message.timestamp) }}</div>
            </div>
          </div>
        </template>
      </div>
      <van-loading v-if="loadingMore" size="20px" color="#1677ff" class="loading-more">加载中...</van-loading>
      <div v-if="!hasMore && messages.length > 0" class="no-more">没有更多消息了</div>
    </div>

    <!-- 输入框区域 -->
    <div class="chat-input-area">
      <div class="chat-input-wrapper">
        <van-field
          v-model="inputMessage"
          placeholder="输入消息..."
          :border="false"
          class="chat-input"
          @keyup.enter="sendMessage"
          :autosize="{ minHeight: 36, maxHeight: 100 }"
        />
        <van-button 
          type="primary" 
          size="small" 
          class="send-btn"
          :disabled="!inputMessage.trim()"
          @click="sendMessage"
        >
          发送
        </van-button>
      </div>
    </div>

    <!-- 更多选项弹窗 -->
    <van-popup
      v-model="showMore"
      position="bottom"
      :style="{ height: 'auto' }"
      round
    >
      <div class="more-options">
        <div class="option-item" @click="clearChat">
          <van-icon name="delete-o" />
          <span>清空聊天记录</span>
        </div>
        <div class="option-item" @click="blockUser">
          <van-icon name="close" />
          <span>屏蔽用户</span>
        </div>
        <div class="option-item" @click="reportUser">
          <van-icon name="warning-o" />
          <span>举报用户</span>
        </div>
      </div>
    </van-popup>
  </div>
</template>

<script>
import { Toast } from 'vant';
import { getChatMessages } from '@/api/api.js';

export default {
  name: 'Chat',
  data() {
    return {
      chatUser: {
        id: '',
        name: '',
        avatar: '',
        status: '在线'
      },
      currentUser: {
        avatar: 'https://img.yzcdn.cn/vant/cat.jpeg'
      },
      messages: [],
      inputMessage: '',
      showMore: false,
      messageContainer: null,
      // 分页相关
      page: 1,
      pageSize: 20,
      total: 0,
      loading: false,
      loadingMore: false,
      hasMore: true,
      scrollToBottomOnNextTick: false
    }
  },
  mounted() {
    this.initChat();
  },
  methods: {
    async initChat() {
      // 从路由参数获取聊天用户信息
      const { userId, userName, userAvatar } = this.$route.query;
      this.chatUser = {
        id: userId || '1',
        name: userName || '张三',
        avatar: userAvatar || 'https://img.yzcdn.cn/vant/cat.jpeg',
        status: '在线'
      };
      this.page = 1;
      this.messages = [];
      this.hasMore = true;
      await this.loadMessages(true);
      this.$nextTick(() => this.scrollToBottom());
    },
    async loadMessages(isInit = false) {
      if (this.loading || this.loadingMore || !this.hasMore) return;
      if (isInit) {
        this.loading = true;
      } else {
        this.loadingMore = true;
      }
      try {
        const res = await getChatMessages({
          page: this.page,
          pageSize: this.pageSize,
          userId: this.chatUser.id
        });
        if (res.data && res.status === 0 && res.data) {
          const rows = res.data.rows || [];
          this.total = res.data.total;
          // 适配数据结构
          const newMsgs = rows.map(item => ({
            ...item,
            isSelf: item.isSend === 1
          }));
          if (isInit) {
            this.messages = newMsgs.reverse(); // 第一页最新在底部
          } else {
            // 加载历史，拼接到前面
            this.messages = [...newMsgs.reverse(), ...this.messages];
          }
          // 判断是否还有更多
          if (this.messages.length >= this.total || rows.length < this.pageSize) {
            this.hasMore = false;
          }
        } else {
          this.hasMore = false;
        }
      } catch (e) {
        Toast('消息加载失败');
      } finally {
        this.loading = false;
        this.loadingMore = false;
      }
    },
    async onScroll(e) {
      const container = e.target;
      if (container.scrollTop === 0 && this.hasMore && !this.loadingMore) {
        // 记录当前高度
        const oldHeight = container.scrollHeight;
        this.page++;
        await this.loadMessages();
        this.$nextTick(() => {
          // 保持滚动位置不变
          container.scrollTop = container.scrollHeight - oldHeight;
        });
      }
    },
    scrollToBottom() {
      this.$nextTick(() => {
        if (this.$refs.messageContainer) {
          this.$refs.messageContainer.scrollTop = this.$refs.messageContainer.scrollHeight;
        }
      });
    },
    formatTime(ts) {
      if (!ts) return '';
      const time = new Date(ts * 1000);
      const now = new Date();
      const diff = now - time;
      if (diff < 60000) {
        return '刚刚';
      } else if (diff < 3600000) {
        return `${Math.floor(diff / 60000)}分钟前`;
      } else if (diff < 86400000) {
        return `${Math.floor(diff / 3600000)}小时前`;
      } else {
        return time.toLocaleDateString();
      }
    },
    goBack() {
      this.$router.back();
    },
    goToUserProfile() {
      this.$router.push({
        path: '/userProfile',
        query: {
          userId: this.chatUser.id,
          userName: this.chatUser.name,
          userAvatar: this.chatUser.avatar
        }
      });
    },
    goToMyProfile() {
      this.$router.push('/my');
    },
    showMoreOptions() {
      this.showMore = true;
    },
    clearChat() {
      this.$dialog.confirm({
        title: '确认清空',
        message: '确定要清空所有聊天记录吗？',
      }).then(() => {
        this.messages = [];
        Toast('聊天记录已清空');
        this.showMore = false;
      });
    },
    blockUser() {
      this.$dialog.confirm({
        title: '确认屏蔽',
        message: `确定要屏蔽 ${this.chatUser.name} 吗？`,
      }).then(() => {
        Toast('用户已屏蔽');
        this.showMore = false;
      });
    },
    reportUser() {
      this.$dialog.confirm({
        title: '确认举报',
        message: `确定要举报 ${this.chatUser.name} 吗？`,
      }).then(() => {
        Toast('举报已提交');
        this.showMore = false;
      });
    },
    // 发送消息（这里只做本地追加，实际应调用发送接口）
    sendMessage() {
      if (!this.inputMessage.trim()) return;
      const now = Math.floor(Date.now() / 1000);
      const newMessage = {
        id: 'local_' + now + '_' + Math.random(),
        text: this.inputMessage,
        isSend: 1,
        isSelf: true,
        avatarPath: this.currentUser.avatar,
        timestamp: now,
        disPlayName: '我'
      };
      this.messages.push(newMessage);
      this.inputMessage = '';
      this.scrollToBottom();
      // 实际项目应在此调用发送消息接口
    },
    isEmoji(text) {
      // 简单判断是否为emoji字符（可根据实际表情包类型调整）
      // 这里只判断单个emoji或常见emoji范围
      return /\p{Emoji}/u.test(text);
    },
    isImage(text) {
      // 判断是否为图片链接
      return /^https?:\/\/.+\.(jpg|jpeg|png|gif|webp|bmp|svg)(\?.*)?$/i.test(text);
    },
    previewImage(url) {
      // vant图片预览
      this.$imagePreview ? this.$imagePreview([url]) : window.open(url, '_blank');
    },
    playVideo(message) {
      // 简单弹窗播放，可根据实际需求替换为更复杂的播放器
      this.$dialog.alert({
        title: '视频播放',
        message: `<video src="${message.url}" controls autoplay style="width:100%"></video>`,
        allowHtml: true
      });
    },
    playVoice(message) {
      // 简单播放语音，实际可用audio标签或更复杂的播放器
      if (this._audio) {
        this._audio.pause();
        this._audio = null;
      }
      this._audio = new Audio(message.url);
      this._audio.play();
    },
    formatFileSize(size) {
      if (!size) return '';
      if (size < 1024) return size + 'B';
      if (size < 1024 * 1024) return (size / 1024).toFixed(1) + 'KB';
      return (size / 1024 / 1024).toFixed(1) + 'MB';
    },
    downloadFile(message) {
      if (message.url) {
        window.open(message.url, '_blank');
      } else {
        this.$toast('无法下载文件');
      }
    },
    openLink(url) {
      window.open(url, '_blank');
    }
  }
}
</script>

<style scoped>
.chat-bg {
  height: 100vh;
  background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
  display: flex;
  flex-direction: column;
}

.chat-header {
  background: linear-gradient(135deg, #1677ff 0%, #42d0ea 100%);
  color: #fff;
  padding: 8px 16px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  box-shadow: 0 4px 20px rgba(22, 119, 255, 0.3);
  position: relative;
  z-index: 10;
  /* border-radius: 0 0 20px 20px; */
}

.chat-back {
  font-size: 20px;
  cursor: pointer;
  padding: 8px;
  border-radius: 50%;
  transition: background-color 0.2s;
}

.chat-back:hover {
  background-color: rgba(255, 255, 255, 0.1);
}

.chat-user-info {
  display: flex;
  align-items: center;
  flex: 1;
  justify-content: flex-start;
  cursor: pointer;
  padding: 0 12px 0 0;
  border-radius: 20px;
  transition: background-color 0.2s;
}

.chat-user-info:hover {
  background-color: rgba(255, 255, 255, 0.1);
}

.chat-avatar {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  margin-right: 12px;
  border: 2px solid rgba(255, 255, 255, 0.3);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  transition: transform 0.2s;
}

.chat-avatar:hover {
  transform: scale(1.05);
}

.chat-user-details {
  display: flex;
  flex-direction: column;
}

.chat-user-name {
  font-size: 16px;
  font-weight: 600;
  margin-bottom: 2px;
}

.chat-user-status {
  font-size: 12px;
  opacity: 0.9;
  display: flex;
  align-items: center;
  gap: 4px;
}

.status-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #52c41a;
}

.status-dot.offline {
  background: #999;
}

.chat-more {
  font-size: 20px;
  cursor: pointer;
  padding: 8px;
  border-radius: 50%;
  transition: background-color 0.2s;
}

.chat-more:hover {
  background-color: rgba(255, 255, 255, 0.1);
}

.chat-messages {
  flex: 1;
  padding: 16px 8px;
  overflow-y: auto;
  background: transparent;
  overflow-x: hidden;
}

.message-item {
  display: flex;
  align-items: flex-start;
  margin-bottom: 20px;
  animation: fadeInUp 0.3s ease-out;
  max-width: 100vw;
  box-sizing: border-box;
}

@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.message-self {
  flex-direction: row-reverse;
}

.message-avatar {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  margin: 0 8px;
  cursor: pointer;
  border: 2px solid #fff;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
  transition: transform 0.2s, box-shadow 0.2s;
  flex-shrink: 0;
}

.message-avatar:hover {
  transform: scale(1.1);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
}

.message-content {
  max-width: 70vw;
  min-width: 60px;
  word-break: break-all;
  box-sizing: border-box;
}

.message-bubble {
  background: #fff;
  border-radius: 10px;
  padding: 10px 10px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
  position: relative;
  border: 1px solid rgba(0, 0, 0, 0.05);
  transition: transform 0.2s;
  max-width: 100%;
  word-break: break-all;
  white-space: pre-line;
  box-sizing: border-box;
}

.message-bubble:hover {
  transform: translateY(-1px);
}

.message-self .message-bubble {
  background: linear-gradient(135deg, #1677ff 0%, #42d0ea 100%);
  color: #fff;
  box-shadow: 0 2px 12px rgba(22, 119, 255, 0.3);
}

.message-text {
  font-size: 15px;
  line-height: 1.5;
  word-break: break-word;
  margin-bottom: 4px;
}

.message-time {
  font-size: 11px;
  opacity: 0.7;
  text-align: right;
  margin-top: 4px;
}

.chat-input-area {
  background: #fff;
  padding: 8px;
  border-top: 1px solid #e8e8e8;
  box-shadow: 0 -4px 20px rgba(0, 0, 0, 0.1);
  /* border-radius: 20px 20px 0 0; */
}

.chat-input-wrapper {
  display: flex;
  align-items: flex-end;
  gap: 12px;
}

.chat-input {
  flex: 1;
  background: #f8f9fa;
  border-radius: 8px;
  padding: 8px 16px;
  border: 1px solid #e9ecef;
  transition: border-color 0.2s, box-shadow 0.2s;
}

.chat-input:focus-within {
  border-color: #1677ff;
  box-shadow: 0 0 0 3px rgba(22, 119, 255, 0.1);
}

.chat-input :deep(.van-field__control) {
  background: transparent;
  border: none;
  font-size: 15px;
  min-height: 20px;
  max-height: 80px;
  resize: none;
}

.send-btn {
  border-radius: 20px;
  padding: 8px 20px;
  font-size: 14px;
  font-weight: 500;
  height: 36px;
  min-width: 60px;
  background: linear-gradient(135deg, #1677ff 0%, #42d0ea 100%);
  border: none;
  transition: transform 0.2s, box-shadow 0.2s;
}

.send-btn:hover:not(:disabled) {
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(22, 119, 255, 0.3);
}

.send-btn:disabled {
  background: #ccc;
  transform: none;
  box-shadow: none;
}

.more-options {
  padding: 20px;
  background: #fff;
  border-radius: 20px 20px 0 0;
}

.option-item {
  display: flex;
  align-items: center;
  padding: 16px 0;
  border-bottom: 1px solid #f0f0f0;
  cursor: pointer;
  font-size: 16px;
  transition: background-color 0.2s;
  border-radius: 8px;
  margin-bottom: 4px;
}

.option-item:last-child {
  border-bottom: none;
  margin-bottom: 0;
}

.option-item:hover {
  background-color: #f8f9fa;
}

.option-item .van-icon {
  margin-right: 12px;
  font-size: 18px;
  color: #666;
}

.option-item:active {
  background-color: #e9ecef;
}

/* 自定义滚动条 */
.chat-messages::-webkit-scrollbar {
  width: 4px;
}

.chat-messages::-webkit-scrollbar-track {
  background: transparent;
}

.chat-messages::-webkit-scrollbar-thumb {
  background: rgba(0, 0, 0, 0.2);
  border-radius: 2px;
}

.chat-messages::-webkit-scrollbar-thumb:hover {
  background: rgba(0, 0, 0, 0.3);
}

.message-system {
  justify-content: center;
  flex-direction: row;
  display: flex;
  margin: 18px 0;
}
.system-message-content {
  background: #f0f0f0;
  color: #888;
  font-size: 13px;
  border-radius: 12px;
  padding: 8px 18px;
  text-align: center;
  max-width: 70vw;
  box-shadow: 0 1px 4px #0001;
  margin: 0 auto;
  line-height: 1.7;
  word-break: break-all;
  white-space: pre-line;
  box-sizing: border-box;
}

.emoji-bubble {
  background: transparent !important;
  box-shadow: none !important;
  border: none !important;
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 48px;
  min-height: 48px;
  padding: 0;
  max-width: 70vw;
  box-sizing: border-box;
}
.emoji-content {
  font-size: 38px;
  line-height: 1.1;
  display: inline-block;
  max-width: 48px;
  max-height: 48px;
  overflow: hidden;
  word-break: break-all;
}
.emoji-img {
  width: auto;
  height: auto;
  max-width: 48px;
  max-height: 48px;
  display: inline-block;
  object-fit: contain;
  box-sizing: border-box;
}

.video-bubble {
  background: transparent !important;
  box-shadow: none !important;
  border: none !important;
  padding: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  max-width: 180px;
  min-width: 80px;
}
.video-thumb-wrapper {
  position: relative;
  width: 120px;
  height: 80px;
  border-radius: 10px;
  overflow: hidden;
  background: #000;
  cursor: pointer;
  margin-bottom: 4px;
}
.video-thumb {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.video-play-btn {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  font-size: 32px;
  color: #fff;
  background: rgba(0,0,0,0.3);
  border-radius: 50%;
  padding: 4px;
  pointer-events: none;
}
.voice-bubble {
  background: #e6f7ff !important;
  color: #1677ff !important;
  box-shadow: none !important;
  border: none !important;
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 60px;
  max-width: 180px;
  cursor: pointer;
  font-size: 16px;
  padding: 10px 18px;
}
.voice-icon {
  font-size: 22px;
}
.voice-duration {
  font-size: 15px;
  color: #1677ff;
}
.pic-img {
  max-width: 160px;
  max-height: 160px;
  border-radius: 10px;
  box-shadow: 0 2px 8px #0002;
  cursor: pointer;
  object-fit: contain;
  display: block;
}
.card-bubble {
  background: #f8f9fa !important;
  border: 1px solid #e6e6e6 !important;
  box-shadow: 0 2px 8px #0001 !important;
  padding: 12px 14px !important;
  min-width: 120px;
  max-width: 220px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.refer-block {
  background: #f0f0f0;
  border-left: 4px solid #1677ff;
  padding: 6px 10px;
  border-radius: 6px;
  margin-bottom: 4px;
}
.refer-title {
  font-size: 12px;
  color: #1677ff;
  font-weight: bold;
  margin-bottom: 2px;
}
.refer-content {
  font-size: 13px;
  color: #666;
}
.file-block {
  display: flex;
  align-items: center;
  background: #e6f7ff;
  border-radius: 8px;
  padding: 8px 10px;
  cursor: pointer;
  gap: 8px;
}
.file-icon {
  font-size: 22px;
  color: #1677ff;
}
.file-info {
  flex: 1;
  min-width: 0;
}
.file-name {
  font-size: 14px;
  color: #222;
  font-weight: 500;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.file-size {
  font-size: 12px;
  color: #888;
}
.file-arrow {
  font-size: 16px;
  color: #bbb;
}
.link-block {
  display: flex;
  align-items: flex-start;
  background: #fffbe6;
  border-radius: 8px;
  padding: 8px 10px;
  cursor: pointer;
  gap: 8px;
  border: 1px solid #ffe58f;
}
.link-thumb {
  width: 48px;
  height: 48px;
  border-radius: 6px;
  object-fit: cover;
  flex-shrink: 0;
}
.link-info {
  flex: 1;
  min-width: 0;
}
.link-title {
  font-size: 14px;
  color: #222;
  font-weight: 500;
  margin-bottom: 2px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.link-desc {
  font-size: 12px;
  color: #888;
  margin-bottom: 2px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.link-url {
  font-size: 12px;
  color: #1677ff;
  word-break: break-all;
}
.link-arrow {
  font-size: 16px;
  color: #bbb;
  margin-left: 2px;
}
.transfer-block {
  display: flex;
  align-items: center;
  background: #fff0f6;
  border-radius: 8px;
  padding: 10px 14px;
  gap: 10px;
  border: 1px solid #ffadd2;
}
.transfer-icon {
  font-size: 22px;
  color: #ff3b30;
}
.transfer-info {
  flex: 1;
  min-width: 0;
}
.transfer-amount {
  font-size: 16px;
  color: #ff3b30;
  font-weight: bold;
}
.transfer-memo {
  font-size: 13px;
  color: #888;
}
.card-default {
  font-size: 14px;
  color: #666;
  padding: 4px 0;
}
</style> 